package com.xuanyuanxinyu.func.network.internal

import android.util.Log
import com.xuanyuanxinyu.utils.log.AppLog
import okhttp3.Call
import okhttp3.Connection
import okhttp3.EventListener
import okhttp3.Handshake
import okhttp3.Protocol
import okhttp3.Request
import okhttp3.Response
import java.io.IOException
import java.net.InetAddress
import java.net.InetSocketAddress
import java.net.Proxy

/**
 * EventListener监听实现类
 */
class OkHttpEventListener : EventListener() {
    /**
     * 请求开始
     */
    private var mCallStartTime : Long = 0
    private var mDnsStartTime : Long = 0
    private var mConnectStartTime : Long = 0
    private var mSecureConnectStartTime : Long = 0
    private var mConnectionStartTime : Long = 0
    private var mRequestHeadersStartTime : Long = 0
    private var mRequestBodyStartTime : Long = 0
    private var mResponseHeadersStartTime : Long = 0
    private var mResponseBodyStartTime : Long = 0
    
    /**
     * 请求开始
     */
    override fun callStart(call : Call) {
        super.callStart(call)
        mCallStartTime = System.nanoTime()
        if (AppLog.PRINT_LOG) {
            Log.w("OkHttpEventListener", call.request().method + " " + call.request().url.toString() + "  1. 方法的 callStart  监听开始**********************************")
        }
    }
    
    /**
     * 请求正常结束
     */
    override fun callEnd(call : Call) {
        super.callEnd(call)
        logMethod(call.request().method + " " + call.request().url.toString() + "  10. 方法的 callEnd  监听结束**********************************", mCallStartTime)
    }
    
    /**
     * 请求异常结束
     */
    override fun callFailed(call : Call,ioe : IOException) {
        super.callFailed(call,ioe)
        logMethod(call.request().method + " " + call.request().url.toString() + "方法的 callFailed",mCallStartTime,true)
    }
    
    /**
     * dns解析开始
     * DNS解析是请求DNS（Domain Name System）服务器。将域名解析成ip的过程。
     */
    override fun dnsStart(call : Call,domainName : String) {
        super.dnsStart(call,domainName)
        mDnsStartTime = System.nanoTime()
    }
    
    /**
     * dns解析结束
     */
    override fun dnsEnd(call : Call,domainName : String,inetAddressList : List<InetAddress>) {
        super.dnsEnd(call,domainName,inetAddressList)
        logMethod(call.request().method + " " + call.request().url.toString() + "  2. 方法的 dnsEnd",mDnsStartTime)
    }
    
    /**
     * 连接开始
     */
    override fun connectStart(call : Call,inetSocketAddress : InetSocketAddress,proxy : Proxy) {
        super.connectStart(call,inetSocketAddress,proxy)
        mConnectStartTime = System.nanoTime()
    }
    
    /**
     * 连接结束
     */
    override fun connectEnd(call : Call,inetSocketAddress : InetSocketAddress,proxy : Proxy,protocol : Protocol?) {
        super.connectEnd(call,inetSocketAddress,proxy,protocol)
        logMethod(call.request().method + " " + call.request().url.toString() + "  3. 方法的 connectEnd",mConnectStartTime)
    }
    
    /**
     * 连接失败
     */
    override fun connectFailed(call : Call,inetSocketAddress : InetSocketAddress,proxy : Proxy,protocol : Protocol?,ioe : IOException) {
        super.connectFailed(call,inetSocketAddress,proxy,protocol,ioe)
        logMethod(call.request().method + " " + call.request().url.toString() + "方法的 connectFailed",mConnectStartTime,true)
    }
    
    /**
     * TLS安全连接开始
     */
    override fun secureConnectStart(call : Call) {
        super.secureConnectStart(call)
        mSecureConnectStartTime = System.nanoTime()
    }
    
    /**
     * TLS安全连接结束
     */
    override fun secureConnectEnd(call : Call,handshake : Handshake?) {
        super.secureConnectEnd(call,handshake)
        logMethod(call.request().method + " " + call.request().url.toString() + "  4. 方法的 secureConnectEnd",mSecureConnectStartTime)
    }
    
    /**
     * 连接绑定
     */
    override fun connectionAcquired(call : Call,connection : Connection) {
        super.connectionAcquired(call,connection)
        mConnectionStartTime = System.nanoTime()
    }
    
    /**
     * 连接释放
     */
    override fun connectionReleased(call : Call,connection : Connection) {
        super.connectionReleased(call,connection)
        logMethod(call.request().method + " " + call.request().url.toString() + "  9. 方法的 connectionReleased",mConnectionStartTime)
    }
    
    /**
     * 请求Header开始
     */
    override fun requestHeadersStart(call : Call) {
        super.requestHeadersStart(call)
        mRequestHeadersStartTime = System.nanoTime()
    }
    
    /**
     * 请求Header结束
     */
    override fun requestHeadersEnd(call : Call,request : Request) {
        super.requestHeadersEnd(call,request)
        logMethod(call.request().method + " " + call.request().url.toString() + "  6. 方法的 requestHeadersEnd",mRequestHeadersStartTime)
    }
    
    /**
     * 请求Body开始
     */
    override fun requestBodyStart(call : Call) {
        super.requestBodyStart(call)
        mRequestBodyStartTime = System.nanoTime()
    }
    
    /**
     * 请求Body结束
     */
    override fun requestBodyEnd(call : Call,byteCount : Long) {
        super.requestBodyEnd(call,byteCount)
        logMethod(call.request().method + " " + call.request().url.toString() + "  7. 方法的 requestBodyEnd",mRequestBodyStartTime)
    }
    
    /**
     * 响应Header开始
     */
    override fun responseHeadersStart(call : Call) {
        super.responseHeadersStart(call)
        mResponseHeadersStartTime = System.nanoTime()
    }
    
    /**
     * 响应Header结束
     */
    override fun responseHeadersEnd(call : Call,response : Response) {
        super.responseHeadersEnd(call,response)
        logMethod(call.request().method + " " + call.request().url.toString() + "  8. 方法的 responseHeadersEnd",mResponseHeadersStartTime)
    }
    
    /**
     * 响应Body开始
     */
    override fun responseBodyStart(call : Call) {
        super.responseBodyStart(call)
        mResponseBodyStartTime = System.nanoTime()
    }
    
    /**
     * 响应Body结束
     */
    override fun responseBodyEnd(call : Call,byteCount : Long) {
        super.responseBodyEnd(call,byteCount)
        logMethod(call.request().method + " " + call.request().url.toString() + "  5. 方法的 responseBodyEnd", mResponseBodyStartTime)
    }
    
    private fun logMethod(name : String,startTime : Long,errorLevel : Boolean = false) {
        if (AppLog.PRINT_LOG) {
            val time = (System.nanoTime() - startTime) / 1000000.0
            if (time > 200 || errorLevel) {
                Log.e("OkHttpEventListener",name + "方法耗时：" + time + "ms")
            } else {
                Log.d("OkHttpEventListener",name + "方法耗时：" + time + "ms")
            }
        }
    }
}